const {v4: uuidv4} = require('uuid');
const createModel = require('../mongodb/createModel')
const path = require('path');
const fs = require('fs');
const mime = require('mime-types');

// 文件模型
const schema = {
    // 用户ID
    userId: {type: String, required: true},
    // 文件ID
    fileId: {type: String, required: true},
    // 文件名
    fileName: {type: String, required: true},
    // 文件扩展名
    extname: {type: String, required: true},
    // 创建时间
    createTime: {type: Date, default: Date.now}
}

const model = createModel('files', schema);

/**
 * 文件上传
 * @param userId    用户ID 必传
 * @param file      文件对象
 * @param fileId    文件ID 非必传
 * @returns {Promise<object>} 结果
 */
const handleUpload = ({userId, file, fileId}) => {
    return new Promise(async (resolve, reject) => {

        // 判断是否删除成功
        let isRemoveRsult;
        if (fileId) {
            isRemoveRsult = await handleRemove({userId, fileId}).catch(err => isRemoveRsult = err);
            if(isRemoveRsult.code === 0){
                return reject(isRemoveRsult);
            }
        }

        let fileName = file.name;
        fileId = uuidv4();
        const extname = path.extname(fileName);

        const rs = fs.createReadStream(file.path);                                      // 创建可读流
        let filePath = path.join(__dirname, `../public/upload/${fileId}${extname}`);    // 配置文件存储路径
        const ws = fs.createWriteStream(filePath);                                      // 创建可写流
        rs.pipe(ws);                                                                    // 可读流通过管道写入可写流

        model.create({userId, fileId, fileName, extname}, (err, docs) => {
            if (!err) {
                let data = JSON.parse(JSON.stringify(docs));
                delete data._id;
                delete data.__v;
                resolve({code: 1, data, msg: '上传成功'});
            } else {
                reject({code: 0, data: null, msg: err.message});
            }
        })

    })
}

/**
 * 删除文件
 * @param userId 用户ID
 * @param fileId 文件ID
 * @returns {Promise<object>} 结果
 */
const handleRemove = ({userId, fileId}) => {
    return new Promise((resolve, reject) => {
        model.findOneAndDelete({userId, fileId}, (err, docs) => {
            if (!err) {
                if(docs){
                    let filePath = path.join(__dirname, `../public/upload/${docs.fileId}${docs.extname}`);
                    // 判断给定的路径是否存在
                    if (fs.existsSync(filePath)) {
                        fs.unlinkSync(filePath);
                    }
                    resolve({code: 1, data: null, msg: '删除成功'});
                }else{
                    reject({code: 0, data: null, msg: '操作失败'})
                }
            } else {
                reject({code: 0, msg: err.message});
            }
        })
    })
}

/**
 * 预览
 * @param fileId    文件ID
 * @param ctx       配置请求头
 * @returns {Promise<object>} 结果
 */
const handlePreview = ({fileId}, ctx) => {
    return new Promise((resolve, reject) => {
        model.findOne({fileId}, {_id: 0, __v: 0,}).exec((err, docs) => {
            if (docs) {
                let filePath = path.join(__dirname, `../public/upload/${docs.fileId}${docs.extname}`);
                let file = null;
                try {
                    file = fs.readFileSync(filePath);
                    let mimeType = mime.lookup(filePath); //读取图片文件类型
                    ctx.set('content-type', mimeType); //设置返回类型
                    resolve(file);
                } catch (error) {
                    reject({code: 0, msg: error.message});
                }
            } else {
                reject({code: 0, msg: '操作失败'});
            }
        })
    })
}

/**
 * 文件列表
 * @param params    文件查询
 * @returns {Promise<object>} 结果
 */
const handleList = (params) => {
    return new Promise((resolve, reject) => {
        model.aggregate([
            {
                $match: {
                    $and: [
                        {userId: {$regex: params.userId || '', $options: 'i'}},
                        {fileName: {$regex: params.fileName || '', $options: 'i'}},
                        {extname: {$regex: params.extname || '', $options: 'i'}},
                        params.createTimeStart ? {createTime: { $gte: new Date(params.createTimeStart + ' 00:00:00')} } : {},
                        params.createTimeEnd ? {createTime: { $lte: new Date(params.createTimeEnd + ' 23:59:59')} } : {},
                    ]
                }
            },
            {$sort: {createTime: -1}},
            {$project: {_id: 0, __v: 0}}
        ]).exec((err, docs) => {
            if (!err) {
                resolve({code: 1, data: docs, msg: '查询成功'});
            } else {
                reject({code: 0, data: null, msg: err.message});
            }
        })
    })
}

module.exports = {handleUpload, handleRemove, handlePreview, handleList}
